﻿using Fall.Core.BaseModels;
using Fall.Core.Exceptions;
using Fall.Core.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace Fall.HttpClient
{
    public static class HttpClientExtensions
    {
        #region 无包装类型

        public async static Task<TResult> DeleteAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri)
        {
            var result = await client.DeleteAsync(requestUri);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> DeleteAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, CancellationToken cancellationToken)
        {
            var result = await client.DeleteAsync(requestUri, cancellationToken);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> DeleteAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, CancellationToken cancellationToken)
        {
            var result = await client.DeleteAsync(requestUri, cancellationToken);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> DeleteAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri)
        {
            var result = await client.DeleteAsync(requestUri);
            return await Serialize<TResult>(result);
        }

        public async static Task<TResult> GetAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri)
        {
            var result = await client.GetAsync(requestUri);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> GetAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, CancellationToken cancellationToken)
        {
            var result = await client.GetAsync(requestUri, cancellationToken);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> GetAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri)
        {
            var result = await client.GetAsync(requestUri);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> GetAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, CancellationToken cancellationToken)
        {
            var result = await client.GetAsync(requestUri, cancellationToken);
            return await Serialize<TResult>(result);
        }

        public async static Task<TResult> PatchAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PatchAsync(requestUri, content, cancellationToken);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PatchAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content)
        {
            var result = await client.PatchAsync(requestUri, content);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PatchAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content)
        {
            var result = await client.PatchAsync(requestUri, content);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PatchAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PatchAsync(requestUri, content, cancellationToken);
            return await Serialize<TResult>(result);
        }

        public async static Task<TResult> PostAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content)
        {
            var result = await client.PostAsync(requestUri, content);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PostAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content)
        {
            var result = await client.PostAsync(requestUri, content);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PostAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PostAsync(requestUri, content, cancellationToken);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PostAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PostAsync(requestUri, content, cancellationToken);
            return await Serialize<TResult>(result);
        }

        public async static Task<TResult> PutAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content)
        {
            var result = await client.PutAsync(requestUri, content);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PutAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content)
        {
            var result = await client.PutAsync(requestUri, content);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PutAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PutAsync(requestUri, content, cancellationToken);
            return await Serialize<TResult>(result);
        }
        public async static Task<TResult> PutAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PutAsync(requestUri, content, cancellationToken);
            return await Serialize<TResult>(result);
        }
        #endregion

        #region 有包装类型

        public async static Task<TResult> FallDeleteAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri)
        {
            var result = await client.DeleteAsync(requestUri);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallDeleteAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, CancellationToken cancellationToken)
        {
            var result = await client.DeleteAsync(requestUri, cancellationToken);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallDeleteAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, CancellationToken cancellationToken)
        {
            var result = await client.DeleteAsync(requestUri, cancellationToken);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallDeleteAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri)
        {
            var result = await client.DeleteAsync(requestUri);
            return await FallSerialize<TResult>(result);
        }

        public async static Task<TResult> FallGetAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri)
        {
            var result = await client.GetAsync(requestUri);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallGetAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, CancellationToken cancellationToken)
        {
            var result = await client.GetAsync(requestUri, cancellationToken);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallGetAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri)
        {
            var result = await client.GetAsync(requestUri);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallGetAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, CancellationToken cancellationToken)
        {
            var result = await client.GetAsync(requestUri, cancellationToken);
            return await FallSerialize<TResult>(result);
        }

        public async static Task<TResult> FallPatchAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PatchAsync(requestUri, content, cancellationToken);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPatchAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content)
        {
            var result = await client.PatchAsync(requestUri, content);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPatchAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content)
        {
            var result = await client.PatchAsync(requestUri, content);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPatchAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PatchAsync(requestUri, content, cancellationToken);
            return await FallSerialize<TResult>(result);
        }

        public async static Task<TResult> FallPostAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content)
        {
            var result = await client.PostAsync(requestUri, content);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPostAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content)
        {
            var result = await client.PostAsync(requestUri, content);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPostAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PostAsync(requestUri, content, cancellationToken);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPostAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PostAsync(requestUri, content, cancellationToken);
            return await FallSerialize<TResult>(result);
        }

        public async static Task<TResult> FallPutAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content)
        {
            var result = await client.PutAsync(requestUri, content);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPutAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content)
        {
            var result = await client.PutAsync(requestUri, content);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPutAsync<TResult>(this System.Net.Http.HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PutAsync(requestUri, content, cancellationToken);
            return await FallSerialize<TResult>(result);
        }
        public async static Task<TResult> FallPutAsync<TResult>(this System.Net.Http.HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            var result = await client.PutAsync(requestUri, content, cancellationToken);
            return await FallSerialize<TResult>(result);
        }

        #endregion
        private static async Task<TResult> Serialize<TResult>(HttpResponseMessage httpResponse)
        {
            return await httpResponse.Serialize<TResult>();
        }

        private static async Task<TResult> FallSerialize<TResult>(HttpResponseMessage httpResponse)
        {
            return await httpResponse.FallSerialize<TResult>();
        }
    }
}
